/**
 * 1. state 数据 或 props 数据发生变化，组件就会更新。
 * 2. 调用组件时，没有传递属性，组件也会收到一个 空对象 作为 props
 * 3. 父组件render，子组件一定会跟着render。（子组件会收到一份新的props,就算都是空对象也会认为props变化了）
 *
 * 做性能优化：
 *   1. App 组件 Render, 当前的 Hello 组件完全没有必要 Render . 如何让 Hello 不 Render 呢？
 *      让 Hello 组件继承 PureComponent 即可。
 *      PureComponent 内部实现了 shouldComponentUpdate 的逻辑。
 *      比较 新旧 props 不再是简单的直接比较，而是比较内部的具体的字段有没有增加、修改、删除
 *      {}    {}      没变化，不更新
 *      {name: '张三'}      {name: '张三'}    没变化，不更新
 *      {name: '张三'}      {name: '李四'}    有变化，会更新
 *      {name: '张三'}      {name: '张三', age: 18}    有变化，会更新
 *      {age: 18, onClick: f}     {age: 18, onClick: f}     没有变化，不更新
 *
 *   2. 四种改变this指向的方案为什么有两种推荐，两种不推荐了。
 *      1. jsx 中直接 bind
 *      2. （推荐）构造函数中提前 bind
 *      3. jsx 中写箭头函数
 *      4. （推荐）事件处理函数定义时，采用 = 箭头函数的语法
 */

import React from "react";

import Hello from "./components/Hello";

class App extends React.Component {
  state = {
    name: "张三",
    age: 18,
  };

  constructor() {
    super();

    this.fn1 = this.fn1.bind(this);
  }

  changeName(newName) {
    this.setState({
      name: newName,
    });
  }

  fn1() {}

  fn2 = () => {};

  render() {
    console.log("App Render");

    const { name, age } = this.state;
    return (
      <div>
        <h1>App</h1>
        <button onClick={() => this.changeName("李四")}>
          我的名字是：{name}
        </button>
        <hr />

        {/* 按钮点击，Hello 是不会更新的 */}
        {/* <Hello age={age} /> */}

        {/* 按钮点击，Hello 是不会更新的 */}
        {/* <Hello age={age} onClick={this.changeName} /> */}

        {/* 按钮点击，Hello 会更新
          bind 会返回一份新函数，这段代码再次执行时 bind 返回的又是一个全新的函数，
          Hello 组件内部 PureComponent 做比较时，认为 onClick 的值是不同。
        */}
        {/* <Hello age={age} onClick={this.changeName.bind(this)} /> */}

        {/* 按钮点击，Hello 是不会更新的 */}
        {/* <Hello age={age} onClick={this.fn1} /> */}

        {/* 按钮点击，Hello 会更新
          代码执行到这，会创建一个箭头函数，再次执行到这，会再次创建一个新的箭头函数
          他们两个函数不是同一份箭头函数。
          所以 Hello 组件内部 PureComponent 比较时，认为有变化，会更新
        */}
        {/* <Hello age={age} onClick={() => this.fn1()} /> */}

        {/* 按钮点击，Hello 是不会更新的 */}
        <Hello age={age} onClick={this.fn2} />
      </div>
    );
  }
}

export default App;
